/*
 * QTeXPreview
 * Copyright (C) 2008, Philip Pronin (philip.pronin@gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "tex.h"
#include "render.h"

#include <QApplication>
#include <QDrag>
#include <QMouseEvent>
#include <QPainter>

RenderAreaWidget::RenderAreaWidget(QWidget* parent) :
	QWidget(parent), vertical(false), renderState(Waiting), eq("") {
	frontEnd = TeXFrontEnd::create(this);
	connect(frontEnd, SIGNAL(renderStarted()), SLOT(renderStarted()));
	connect(frontEnd, SIGNAL(renderFinished(QByteArray)), SLOT(renderFinished(QByteArray)));
}

QSize RenderAreaWidget::minimumSizeHint() const {
	QSize result(210, 105);
	if (isVertical()) result.transpose();
	return result;
}

void RenderAreaWidget::paintEvent(QPaintEvent*) {
	QPainter painter(this);
	QRect rect = this->rect();

	if (isVertical()) {
		QSize s = rect.size();
		s.transpose();
		rect.setSize(s);
		painter.translate(rect.left(), rect.top() + rect.width());
		painter.rotate(-90);
		painter.translate(-rect.left(), -rect.top());
	}

	painter.drawPixmap(rect.left() + (rect.width() - image.width()) / 2,
		rect.top() + (rect.height() - image.height()) / 2, image);
}

void RenderAreaWidget::setRenderState(RenderState state) {
	emit renderStateChanged(renderState = state);
}

void RenderAreaWidget::renderStarted() {
	setRenderState(Rendering);
}

void RenderAreaWidget::renderFinished(QByteArray data) {
	if (data.isEmpty() || !image.loadFromData(data)) image = QPixmap();
	repaint();

	setRenderState(Waiting);
}

void RenderAreaWidget::setTeX(const QString& equation) {
	frontEnd->render(eq = equation);
}

const QPixmap& RenderAreaWidget::getPixmap() const {
	return image;
}

QImage RenderAreaWidget::getImage() const {
	QImage res = getPixmap().toImage();

	if (!res.isNull())
		for (int i = 0; i < res.width(); i++) for (int j = 0; j < res.height(); j++)
			if (!qAlpha(res.pixel(i, j))) res.setPixel(i, j, qRgba(255, 255, 255, 0));

	return res;
}

void RenderAreaWidget::mousePressEvent(QMouseEvent* event) {
	if (event->button() == Qt::LeftButton) dragPosition = event->pos();
	dragImageMode = !(event->modifiers() & Qt::AltModifier);
}

void RenderAreaWidget::mouseMoveEvent(QMouseEvent* event) {
	if (!(event->buttons() & Qt::LeftButton)) return;
	if ((event->pos() - dragPosition).manhattanLength() < QApplication::startDragDistance())
		return;

	QDrag* drag = new QDrag(this);
	QMimeData* mimeData = new QMimeData;
	if (dragImageMode) {
		mimeData->setImageData(getImage());
		drag->setPixmap(QPixmap(":/main/22x22/image-x-xpixmap.png"));
	} else {
		mimeData->setText(eq);
		drag->setPixmap(QPixmap(":/main/22x22/text-x-tex.png"));
	}

	drag->setMimeData(mimeData);

	QWidget* mainWindow = QApplication::activeWindow();
	if (mainWindow) mainWindow->hide();
	drag->exec();
	if (mainWindow) mainWindow->show();
}
